#coding=utf-8
# ----------------导入第三方库----------------
import os
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.svm import SVC, SVR
from tqdm import tqdm
from sklearn.tree import DecisionTreeRegressor
from sklearn.linear_model import LinearRegression
from sklearn.neighbors import KNeighborsRegressor
from sklearn.svm import SVR
from sklearn.linear_model import Lasso
from sklearn.linear_model import Ridge
from sklearn.neural_network import MLPRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.tree import ExtraTreeRegressor
from xgboost import XGBRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import AdaBoostRegressor
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.ensemble import BaggingRegressor


# ----------------加载数据----------------
path = '数据集/'

"""
这里name就是将商品数据进行加工后的的数据列名，从name中可以看到，除了'下周日均销量'外
其他均为商品以一周为单所构建的特征
"""
name = ['日均_总销量', '日均_浏览量', '日均_抖音转化率', '日均_视频个数',
        '日均_直播个数', '日均_直播销量', '日均_视频销量', '日均_视频达人',
        '日均_直播达人', '1_日均销量', '2_日均销量', '3_日均销量', '4_日均销量',
        '5_日均销量', '6_日均销量', '7_日均销量', '下周日均销量']

files = os.listdir(path)
# os.listdir 能够返回文件夹中所有文件名称
all_result = []
# tqdm能够显示列表的遍历进度，能很方便的监控运行状态
for file in tqdm(files):
    tempdata = []
    data = pd.read_csv(path + file)
    id_name = str(data[:1]['商品id'][0])
    result = [id_name]  # id_name 是每个商品的名称

    # ----------------特征工程----------------
    """
    这里针对每个商品，以一周为单位进行特征的构造，包括有一周的相关数据，具体见
    加载数据中的name变量，将174天的数据加工成了167行的用于构建模型的数据
    """
    for i in range(0, 167):
        # 从当前开始，到下一周的数据均值
        this_week = list((data[i:i + 7].iloc[:, 2:]).mean())
        # 下周日均销量
        next_week_sales_sum = data[i + 7:i + 14]['总销量'].mean()
        # 当前周每一天到下6天日均销量
        week_salse_list = []
        for week in range(7):
            diff_week_sales = data[i + week:i + 7 + week]['总销量'].mean()
            week_salse_list.append(diff_week_sales)
        # 数据更新
        this_week.extend(week_salse_list)
        this_week.append(next_week_sales_sum)
        tempdata.append(this_week)

    # ----------------构建训练集、测试集---------------

    s1 = pd.DataFrame(tempdata, columns=name)
    train = s1[:-1]
    train_label = train['下周日均销量']
    train = train.drop(['下周日均销量'], axis=1)
    test = s1[-1:].iloc[:, :-1]
    #iloc[a:b,c:d]:取行索引从a到b-1，列索引从c到d-1的数据。
    # ----------------模型训练---------------
    """
    这里使用的模型是决策回归树模型，也可以尝试其他的模型
    线性回归   from sklearn.linear_model import LinearRegression
    支持向量机 from sklearn.svm import SVR
    K近邻回归  from sklearn.neighbors import KNeighborsRegressor
    随机森林回归 from sklearn.ensemble import RandomForestRegressor
    回归模型
    总结：不同的模型需要训练数据的形式是不同的
    需要对x,y都标准化处理的模型有：[‘MLPRegressor’,‘AdaBoost’,‘Bagging’,‘ExtraTree’]
    需要只对y平滑处理的有：[‘LinearRegression’,‘Ridge’]
    需要对y和x中的连续型数据标准化处理的模型：[‘SVR’,‘KNNRegressor’]
    剩下的5个模型不需要对x和y进行处理：[‘Lasso’,‘DecisionTree’,‘XGBoost’,‘RandomForest’,‘GradientBoost’]
    准确率最高的模型为【‘XGBoost’,‘RandomForest’,‘GradientBoost’】，都是集成学习算法。
    models=[LinearRegression(),
    KNeighborsRegressor(),
    SVR(),
    Ridge(),
    Lasso(),
    MLPRegressor(alpha=20),
    DecisionTreeRegressor(),
    ExtraTreeRegressor(),
    XGBRegressor(),
    RandomForestRegressor(),
    AdaBoostRegressor(),
    GradientBoostingRegressor(),
    BaggingRegressor()]
    """
    # model = DecisionTreeRegressor()
    # model = SVR()
    # svm = make_pipeline(StandardScaler(), SVC(gamma='auto'))SVR训练数据需要标准化处理
    # model = KNeighborsRegressor()
    model = RandomForestRegressor()
    # model = GradientBoostingRegressor()
    # model = XGBRegressor()
    # 训练模型
    model.fit(train, train_label)
    # 训练下一周的日均销量
    pre_y = model.predict(test)[0]
    # 如果模型预测的值为负，显然没有业务意义，就校正为0
    if pre_y < 0:
        pre_y = 0
    result.append(pre_y)
    # 将每个商品的销量预测存在all_result中
    all_result.append(result)
    print(all_result.append(result))

# ----------------结果输出----------------
"""
这一步就是将结果存储到字典中，因为提交示例的顺序商品的顺序都是乱序的
代码会生成 result.csv这个文件，这也是最后需要提交的结果文件
"""
all_result_df = pd.DataFrame(all_result)
rmap = {}
for index, row in all_result_df.iterrows():
    rmap[row[0]] = row[1]

rdata = pd.read_csv('提交示例.csv')
# 按照提交示例格式输出提交结果
rdata['未来一周天均销量'] = rdata['商品id'].map(rmap)
rdata.to_csv('result-RandomForestRegressor.csv', index=False)